﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PMKB_DAL;
using KVP;
using PagedList;
using common;
namespace PMKB_Repository
{
    public class DisplayTag
    {
        public I_Tag tag;
        public IPagedList<I_Link_OLAP> links;
    }
    public class clsLoadTags
    {
        public string ConnectionName;
        public List<I_Tag> tagsFromName(string NameTag)
        {
            using (Tag_List tl = new Tag_List(ConnectionName))
            {
                tl.LoadFromDB.LoadFrom_TagName(NameTag);
                
                if (tl.Count == 0)                    
                    tl.LoadFromDB.LoadFrom_TagNameContainsQ(NameTag);

                return tl.ConvertAll(item => (I_Tag)item);

            }
        }
        public I_Tag AddNewTag(string NameTag)
        {
            using (Tag_List tl = new Tag_List(ConnectionName))
            {
                tl.LoadFromDB.LoadFrom_TagName(NameTag);

                if (tl.Count == 0)
                {
                    tl.Add(new Tag() { TagName = NameTag });
                    tl.SaveNew();
                }
                return tl[0];

                

            }
        }
        public List<KVPNew<long, string>> AllTags()
        {
            using (Tag_List col = new Tag_List(ConnectionName))
            {

                col.LoadFromDB.LoadAll();
                return col.ToKVPNew(i1 => i1.TagID, i2 => i2.TagName, true);
            }
        }
        public DisplayTag LoadTag(long id, int pageNumber, int pageSize)
        {
            using (Tag_List tl = new Tag_List(ConnectionName))
            {
                var tag = tl.LoadFromDB.LoadFrom_TagIDQ(id).FirstOrDefault();
                Link_Tag_List tll = new Link_Tag_List(tl);
                var links=tll.LoadFromDB.LoadFrom_TagIDQ(id).OrderBy(item=>item.LinkTagID).ToPagedList(pageNumber,pageSize);
                var linksid=links.Select(item => item.LinkID).ToArray();
                Link_OLAP_List lol = new Link_OLAP_List(tl);
                lol.LoadFromDB.LoadFindIDsColumn_LinkID(linksid);
                DisplayTag dt = new DisplayTag();
                dt.tag = tag;                
                StaticPagedList<I_Link_OLAP> l=new StaticPagedList<I_Link_OLAP>(lol.ConvertAll(item => (I_Link_OLAP)item),links.GetMetaData());
                dt.links = l;
                
                
                return dt;
                
                

            }
        }
        public List<I_Tag> UsedTags()
        {
            string key="tags";
            CacheSystem<List<I_Tag>> cs = new CacheSystem<List<I_Tag>>();
            var data = cs.GetValue(key);
            if (data == null)
            {
                using (Link_Tag_List ltl = new Link_Tag_List(ConnectionName))
                {
                    var idtags = ltl.LoadFromDB.LoadAllQ().Select(item => item.TagID).Distinct().ToArray();
                    Tag_List tl = new Tag_List(ltl);
                    tl.LoadFromDB.LoadFindIDsColumn_TagID(idtags);
                    List<I_Tag> tags = new List<I_Tag>(tl);
                    cs.AddCache(key,tags, 15);//TODO:put 15 on the settings
                }
            }
            return cs.GetValue(key);
        }

        public I_Tag RenameTags(long id, string name)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentException(Tag_List.FieldNames.TagName,Tag_List.FieldNames.TagName);
            
            using (Tag_List tl = new Tag_List(ConnectionName))
            {
                tl.LoadFromDB.LoadFrom_TagID(id);
                string oldname=tl[0].TagName;
                tl[0].TagName = name;
                
                tl.SaveExisting();


                string sql = "update " + HelperTables.NameTable(Tables_PMKBEntities.Link_OLAP) + " set {0}= replace({0},{1},{2})";
                sql = string.Format(sql,Link_OLAP_List.FieldNames.Tags, "{0}","{1}");
                tl.ExecuteSqlCommand(sql,LinkAddOrEdit.WithSeparator(oldname),LinkAddOrEdit.WithSeparator(name));
                return tl[0];
            }
            
        }
        public void UpdateTags(IEnumerable<KVP.KVPNew<long, string>> list)
        {
            using (Tag_List tl = new Tag_List(ConnectionName))
            {
                foreach (var item in list)
                {
                    RenameTags(item.Key, item.Value);
                }
            }
        }
        public IPagedList<KVPNew<long,string>> LoadTags(int pageNumber, int pageSize)
        {
             using (Tag_List tl = new Tag_List(ConnectionName))
             {
                 Link_Tag_List ltl=new Link_Tag_List(tl);
                 var data = tl.LoadFromDB.LoadAllQ()

                     .GroupJoin(
                     ltl.LoadFromDB.LoadAllQ(),
                     t => t.TagID,
                     l => l.TagID,
                     (a, b) => new KVPNew<long, string>() { Key = a.TagID, Value = a.TagName, AdditionalDataLong = b.Count() })                     
                      .OrderByDescending(item => item.AdditionalDataLong);
                 
                 //TODO: verify that does not load all, but makes paging on server
                 return data.ToPagedList(pageNumber,pageSize);

             }
        }
        public void DeleteTag(int id)
        {

            using (Tag_List tl = new Tag_List(ConnectionName))
            {
                Link_Tag_List lt = new Link_Tag_List(tl);
                var nr = lt.LoadFromDB.LoadFrom_LinkTagIDQ(id).Count();
                if (nr > 0)
                {
                    throw new ExceptionUtils.ExceptionFK(PMKBEntities_resource.Tag_Delete_Error);
                }
                tl.Delete_TagID(id);
            }
        }
    }
}
